package com.lbj.mall.ware.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lbj.mall.common.constant.WarePurchaseBill;
import com.lbj.mall.common.constant.WarePurchaseNeed;
import com.lbj.mall.common.utils.PageUtils;
import com.lbj.mall.common.utils.Query;
import com.lbj.mall.common.utils.R;
import com.lbj.mall.ware.dao.PurchaseDao;
import com.lbj.mall.ware.entity.PurchaseDetailEntity;
import com.lbj.mall.ware.entity.PurchaseEntity;
import com.lbj.mall.ware.entity.WareSkuEntity;
import com.lbj.mall.ware.entity.vo.DoneItem;
import com.lbj.mall.ware.entity.vo.DoneVo;
import com.lbj.mall.ware.entity.vo.MergeVo;
import com.lbj.mall.ware.feign.ProductFeign;
import com.lbj.mall.ware.service.PurchaseDetailService;
import com.lbj.mall.ware.service.PurchaseService;
import com.lbj.mall.ware.service.WareSkuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;
    @Autowired
    private WareSkuService wareSkuService;
    @Autowired
    private ProductFeign productFeign;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();


        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params), wrapper);

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryUnReceiveList(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params)
                , new QueryWrapper<PurchaseEntity>().eq("status", 0).or().eq("status", 1));
        return new PageUtils(page);

    }

    @Transactional
    @Override
    public void merge(MergeVo mergeVo) {

        // 判断每个采购项是不是都是新建或已分配状态，如果不是则不能合并采购项
        List<PurchaseDetailEntity> pdList = purchaseDetailService.listByIds(mergeVo.getItems());
        boolean isAgree = true;
        for (PurchaseDetailEntity entity : pdList) {
            Integer status = entity.getStatus();
            if (status != WarePurchaseNeed.NEW.getCode() && status != WarePurchaseNeed.SELECT.getCode()) {
                isAgree = false;
                break;
            }
        }

        log.error("merge -> 采购项中有任务状态非新建状态或已分配状态");

        if (isAgree) {
            Long purchaseId = mergeVo.getPurchaseId();
            // 如果purchaseId是null则需要创建新的采购单
            // 如果不为空则在存在的采购单上更新
            if (purchaseId == null) {
                PurchaseEntity entity = new PurchaseEntity();
                entity.setCreateTime(new Date());
                entity.setUpdateTime(new Date());
                // 状态修改为新建采购单
                entity.setStatus(WarePurchaseBill.NEW.getCode());
                save(entity);
                purchaseId = entity.getId();
            }

            // 合并采购项到采购单上去
            Long finalPurchaseId = purchaseId;
            List<PurchaseDetailEntity> collectList = mergeVo.getItems().stream().map(item -> {
                PurchaseDetailEntity entity = new PurchaseDetailEntity();
                entity.setId(item);
                entity.setPurchaseId(finalPurchaseId);
                entity.setStatus(WarePurchaseNeed.SELECT.getCode());
                return entity;
            }).collect(Collectors.toList());

            purchaseDetailService.updateBatchById(collectList);
        }
    }

    /**
     * 领取采购单
     */
    @Transactional
    @Override
    public void received(List<Long> ids) {
        // 更新采购单中的数据为已领取
        List<PurchaseEntity> purchaseList = ids.stream().map(item -> {
            PurchaseEntity entity = new PurchaseEntity();
            entity.setId(item);
            // 设置该采购单已领取
            entity.setStatus(WarePurchaseBill.GIVE.getCode());
            entity.setUpdateTime(new Date());
            return entity;
        }).collect(Collectors.toList());
        updateBatchById(purchaseList);

        // 更新采购单对应的采购详细中的状态为已领取
        List<PurchaseDetailEntity> purchaseDetailList = purchaseDetailService.listByPurchaseIds(ids);
        List<PurchaseDetailEntity> collectList = purchaseDetailList.stream().map(item -> {
            PurchaseDetailEntity entity = new PurchaseDetailEntity();
            entity.setId(item.getId());
            entity.setStatus(WarePurchaseNeed.STARTING.getCode());
            return entity;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(collectList);
    }

    @Transactional
    @Override
    public void done(DoneVo doneVo) {
        // 所有成功的数据
        List<DoneItem> finishList = new ArrayList<>();

        // 1.所有的采购条目信息调整
        List<DoneItem> items = doneVo.getItems();
        purchaseDetailService.updateBatch(items);

        // 2.采购单信息修改
        boolean isFinish = true;
        for (DoneItem item : items) {
            if (item.getStatus() == null || WarePurchaseNeed.ERROR.getCode() == item.getStatus()) {
                isFinish = false;
                break;
            } else {
                finishList.add(item);
            }
        }
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(doneVo.getId());
        purchaseEntity.setUpdateTime(new Date());
        purchaseEntity.setStatus(isFinish ? WarePurchaseBill.FINISH.getCode() : WarePurchaseBill.ERROR.getCode());
        updateById(purchaseEntity);

        // 3.添加库存信息，如果finishList为空则说明所有采购都失败
        if (finishList.size() != 0) {
            List<PurchaseDetailEntity> purchaseDetailList = purchaseDetailService
                    .listByIds(finishList.stream().map(DoneItem::getItemId).collect(Collectors.toList()));
            List<WareSkuEntity> wareSkuList = purchaseDetailList.stream().map(item -> {
                WareSkuEntity entity = new WareSkuEntity();
                entity.setSkuId(item.getSkuId());
                entity.setWareId(item.getWareId());
                entity.setStock(item.getSkuNum());
                entity.setStockLocked(0);
                // 调用远程服务，获取SKU名字，捕获异常，如果远程服务不可能，保证SQL可以进行下去，只是不会保存SkuName
                // 这样操作如果远程服务调用失败就不会回滚
                try {
                    log.debug("开始调用远程服务");
                    R r = productFeign.info(item.getSkuId());
                    log.debug("R -> " + r.toString());
                    Map<String, Object> skuInfo = (Map<String, Object>) r.get("skuInfo");
                    log.debug("调用远程服务 name -> " + skuInfo.get("skuName"));
                    entity.setSkuName((String) skuInfo.get("skuName"));
                    log.debug("调用远程服务 -> 成功");
                } catch (Exception ignored) {
                    log.debug("调用远程服务 -> 失败");
                }
                return entity;
            }).collect(Collectors.toList());

            wareSkuService.addStock(wareSkuList);
        }
    }
}